<template>
  <div class="app-container">
    <div style=" margin-top: 10px; margin-left: 10px; width: 100%;">
      <el-button size="mini" @click="openDialog(1)">添加一级</el-button>
    </div>
    <el-tree
      ref="tree"
      :data="data5"
      :allow-drop="allowDrop"
      :default-expand-all="false"
      :props="defaultProps"
      :expand-on-click-node="false"
      draggable
      render-after-expand
      node-key="id"
      @node-click="singleClick"
      @node-contextmenu="rightClick"
      @node-drop="handleDrop">
      <span slot-scope="{ node, data }" class="custom-tree-node">
        <span v-if="data.isDictionaryDatas"><i class="el-icon-document"/>{{ node.label }}</span>
        <span v-else><i class="el-icon-message"/>{{ node.label }}</span>
      </span>
    </el-tree>

    <!--右键菜单-->
    <div id="menu">
      <div class="showMenu">
        <p v-if="isFolder" @click="openDialog(1)">新建文件夹</p>
        <p v-if="isFolder" @click="openDialog(2)">编辑文件夹</p>
        <p v-if="isFolder" @click="openDialog(3)">新建数据类型</p>
        <p v-if="isFolder" @click="openDialog(5)">删除文件夹</p>

        <p v-if="!isFolder" @click="openDialog(4)">编辑数据类型</p>
        <p v-if="!isFolder" @click="openDialog(6)">删除数据类型</p>
      </div>
    </div>

    <!--新建 以及 编辑 输入域-->
    <!--文件夹-->
    <el-dialog :visible.sync="dialogVisible" :before-close="handleClose" title="文件夹" width="30%">
      <el-form ref="from" :model="temp" :rules="rules">
        <!-- 新建文件夹 和 编辑文件夹 -->
        <el-form-item prop="fileName">
          <el-input v-model="temp.fileName" placeholder="请输入文件名" clearable />
        </el-form-item>
      </el-form>

      <span slot="footer" class="dialog-footer">
        <el-button @click="hClose">取 消</el-button>
        <el-button v-if="clickNumber == '1' " type="primary" @click="newFolder">确 定</el-button>
        <el-button v-if="clickNumber == '2' " type="primary" @click="editorFolderName">确 定</el-button>
      </span>

    </el-dialog>

    <!--文件 数据类型-->
    <el-dialog :visible.sync="dataDialogVisibleT" :before-close="handleClose" title="数据类型" width="30%">

      <el-form ref="fromT" :model="temp" :rules="rules" label-width="70px" >
        <el-form-item prop="dataTypeName" label="名称">
          <el-input v-model="temp.dataTypeName" placeholder="请输入文件名称" clearable />
        </el-form-item>

        <el-form-item prop="dataTypeCode" label="编码">
          <el-input v-model="temp.dataTypeCode" style="" placeholder="请输入文件编码" clearable />
        </el-form-item>
      </el-form>

      <span slot="footer" class="dialog-footer">
        <el-button @click="hClose">取 消</el-button>
        <el-button v-if="clickNumber == '3'" type="primary" @click="newFile">确 定</el-button>
        <el-button v-if="clickNumber == '4'" type="primary" @click="editorDataType">确 定</el-button>
      </span>
    </el-dialog>

  </div>
</template>

<script>
// getDictionaryData
import { moveDictionaryFolder, fetchDictionaryList, saveDictionary, updateDictionary, saveDictionaryData, updateDictionaryData, deleteDictionaryFolder, deleteDictionaryData } from '@/api/common'
import { codeValidation } from '@/methods/codeValidation'

export default {

  data() {
    return {
      // 所有数据
      data5: [],
      // 用户已有的权限ID
      codePermId: [],

      // 右击的时候 用来判断是否为文件夹 或者 文件
      isFolder: true,

      // 新建以及编辑输入域 是否显示
      dialogVisible: false,
      dataDialogVisibleT: false,

      // 存储 新建 或者 编辑的 相关值
      temp: {
        fileName: '',
        dataTypeCode: '',
        dataTypeName: ''
      },

      // 存储 右击的 对象数据
      rightClickObj: {},

      // 存储 右击菜单中点击的编号
      clickNumber: '',

      // 表达验证
      rules: {
        fileName: [
          { required: true, message: '请输入名称', trigger: 'blur' }
        ],
        dataTypeCode: [
          { required: true, message: '请输入编码', trigger: 'blur' }
        ],
        dataTypeName: [
          { required: true, message: '请输入名称', trigger: 'blur' }
        ]
      },

      // 设置树形结构( tree ) 默认子集 和 标签名 的字段
      defaultProps: {
        children: 'children',
        label: 'name'
      }
    }
  },
  created() {
    this.getDictionaryList()
  },
  methods: {

    // 获取树形结构数据
    getDictionaryList() {
      var self = this
      fetchDictionaryList().then(response => {
        var theModel = response.data.dictionaryFolderRoots
        theModel.forEach((val) => {
          self.pushDictionaryDatas(val)
        })
        self.data5 = theModel
      })
    },

    // 将 dictionaryDatas 放到 children 中
    pushDictionaryDatas(node) {
      var self = this
      if (node.dictionaryDatas) {
        var dd = node.dictionaryDatas
        dd.forEach((val) => {
          // 用来在移动的时候判断是否可以移动
          val['isDictionaryDatas'] = true
          node.children.push(val)
        })
      }

      if (node.children) {
        if (node.children.length > 0) {
          var ch = node.children
          ch.forEach((val) => {
            self.pushDictionaryDatas(val)
          })
        }
      }
    },

    // 判断目标节点是否可以放置
    /* 通过 目标节点 的 childern 长度是否为 0  来判断
    * 当 childern 长度 为 0 , 则为不能拖动
    * */
    allowDrop(draggingNode, dropNode, type) {
      if (dropNode.data.isDictionaryDatas) {
        return false
      } else {
        return true
      }
    },

    handleDrop(draggingNode, dropNode, dropType, ev) {
      console.log('拖拽的节点: ', draggingNode)
      console.log('最后进入的节点: ', dropNode)
      console.log('拖拽节点放置位置: ', dropType)
      var self = this
      var data = {}

      var dgNode = draggingNode.data
      var drNode = dropNode.data

      /* 判断拖拽的是 文件 还是 文件夹 , 分别调用不同的 接口
      isDictionaryDatas 为true 的时候 表示 文件 */
      if (dgNode.isDictionaryDatas) {
        // 当类型为 inner 的时候 说明不是在根目录
        if (dropType === 'inner') {
          data.id = dgNode.id
          data.dictionaryFolderId = drNode.id
          self.moveFile(data)
        } else {
          var code = '1'
          var content = '目标节点不可放置'
          codeValidation(code, content, self)
          self.getDictionaryList()
        }
      } else {
        // 当类型为 inner 的时候 说明不是在根目录
        if (dropType === 'inner') {
          data.parentId = drNode.id
        } else {
          data.parentId = ''
        }
        data.id = dgNode.id
        data.name = dgNode.name
        self.moveFolder1(data)
      }
    },

    // 移动文件夹
    moveFolder1(data) {
      var self = this
      updateDictionary(data).then(response => {
        var code = '0'
        var content = response.content
        codeValidation(code, content, self)
      })
    },

    // 移动文件
    moveFile(data) {
      var self = this
      moveDictionaryFolder(data).then(response => {
        var code = '0'
        var content = response.content
        codeValidation(code, content, self)
      })
    },

    // 某节点单击的时候
    singleClick(data, node, componentSelf) {
      var menu = document.querySelector('#menu')
      // 关闭右击菜单的同事, 也清空临时存储右击对象的数据
      //   /* 菜单定位基于鼠标点击位置 */
      menu.style.left = 0
      menu.style.top = 0
      menu.style.display = 'none'
      this.rightClickObj = {}

      if (data.isDictionaryDatas) {
        this.$emit('singleClickData', data)
      }
    },

    // 某节点右击的时候
    rightClick(event, object, value, element) {
      // var menu = document.querySelector('#menu')
      // 右键菜单的宽高
      var menu = document.getElementById('menu')
      var contentHeight = menu.offsetHeight
      var contentWidth = menu.offsetWidth

      // 浏览器的 宽和高
      // var clientWidth = document.body.clientWidth
      var clientHeight = document.body.clientHeight

      // 鼠标右击的位置
      // var clientX = event.clientX
      var clientY = event.clientY

      if (contentHeight + clientY > clientHeight) {
        menu.style.left = event.clientX - contentWidth + 10 + 'px'
        menu.style.top = event.clientY - contentHeight + 10 + 'px'
      } else {
        //  菜单定位基于鼠标点击位置
        menu.style.left = event.clientX + 'px'
        menu.style.top = event.clientY + 'px'
      }

      menu.style.display = 'block'

      // 将右击的对象 相关数据存储
      this.rightClickObj = object

      if (object.isDictionaryDatas) {
        this.isFolder = false
      } else {
        this.isFolder = true
      }

      console.log('右键被点击的event:', event)
      console.log('右键被点击的object:', object)
      console.log('右键被点击的value:', value)
      console.log('右键被点击的element:', element)
    },

    // 打开弹框
    openDialog(data) {
      var self = this
      var menu = document.querySelector('#menu')
      // 关闭右击菜单的同时, 也清空临时存储右击对象的数据
      //   /* 菜单定位基于鼠标点击位置 */
      menu.style.left = 0
      menu.style.top = 0
      menu.style.display = 'none'

      self.clickNumber = data

      switch (data) {
        case 1:
          self.dialogVisible = true
          break

        case 2:
          self.temp.fileName = self.rightClickObj.name
          self.dialogVisible = true
          break

        case 3:
          self.dataDialogVisibleT = true
          break

        case 4:
          self.dataDialogVisibleT = true
          self.temp.dataTypeCode = self.rightClickObj.code
          self.temp.dataTypeName = self.rightClickObj.name
          break

        case 5:
          self.$confirm('确认删除  ' + self.rightClickObj.name + '  文件夹？')
            .then(_ => {
              self.deleteDictionaryFolder()
            })
            .catch(_ => {})
          break

        case 6:
          self.$confirm('确认删除  ' + self.rightClickObj.name + '  数据类型？')
            .then(_ => {
              self.deleteDictionaryData()
            })
            .catch(_ => {})
          break
      }
    },

    // 新建文件夹
    newFolder() {
      var self = this
      this.$refs[ 'from' ].validate((valid) => {
        if (valid) {
          var data = {
            name: self.temp.fileName,
            parentId: self.Util.nullToString(self.rightClickObj, 'id')
          }
          saveDictionary(data).then(response => {
            this.$nextTick(function() {
              self.$refs['from'].resetFields()
            })
            self.dialogVisible = false
            var dictionaryFolder = response.data.dictionaryFolder
            if (self.Util.isObjEmpty(self.rightClickObj)) {
              self.rightClickObj.children.push(dictionaryFolder)
            } else {
              self.data5.push(dictionaryFolder)
            }
            var code = '0'
            var content = response.content
            codeValidation(code, content, self)
          })
        }
      })
    },

    // 编辑文件夹
    editorFolderName() {
      var self = this
      this.$refs['from'].validate((valid) => {
        if (valid) {
          var temp = {
            id: self.rightClickObj.id,
            name: self.temp.fileName,
            parentId: self.rightClickObj.parentId
          }
          updateDictionary(temp).then(response => {
            var code = '0'
            var content = response.content
            this.$nextTick(function() {
              self.$refs['from'].resetFields()
            })
            self.dialogVisible = false
            // self.getDictionaryList()
            self.rightClickObj.name = self.temp.fileName
            codeValidation(code, content, self)
          })
        }
      })
    },

    // 新建数据类型
    newFile() {
      var self = this
      this.$refs['fromT'].validate((valid) => {
        if (valid) {
          var temp = {
            name: self.temp.dataTypeName,
            dictionaryFolderId: self.Util.nullToString(self.rightClickObj, 'id'),
            code: self.temp.dataTypeCode
          }
          saveDictionaryData(temp).then(response => {
            var code = '0'
            var content = response.content
            // this.getDictionaryList() isDictionaryDatas
            var dictionaryData = response.data.dictionaryData
            dictionaryData.isDictionaryDatas = true
            this.rightClickObj.children.push(dictionaryData)
            this.dataDialogVisibleT = false
            self.$refs['fromT'].resetFields()
            codeValidation(code, content, self)
          })
        }
      })
    },

    // 编辑数据类型
    editorDataType() {
      var self = this
      this.$refs['fromT'].validate((valid) => {
        if (valid) {
          var temp = {
            id: self.rightClickObj.id,
            // dictionaryFolderId: self.rightClickObj.dictionaryFolderId,
            dictionaryFolderId: self.Util.nullToString(self.rightClickObj, 'dictionaryFolderId'),
            code: self.temp.dataTypeCode,
            name: self.temp.dataTypeName
          }
          updateDictionaryData(temp).then(response => {
            var code = '0'
            var content = response.content
            // this.getDictionaryList()
            this.rightClickObj.code = self.temp.dataTypeCode
            this.rightClickObj.name = self.temp.dataTypeName
            this.dataDialogVisibleT = false
            self.$refs['fromT'].resetFields()
            codeValidation(code, content, self)
          })
        }
      })
    },

    // 删除文件夹
    deleteDictionaryFolder() {
      var self = this
      var data = {
        ids: self.rightClickObj.id
      }
      deleteDictionaryFolder(data).then(response => {
        var code = '0'
        var content = response.content

        self.getDictionaryList()
        codeValidation(code, content, self)
      })
    },

    // 删除数据类型
    deleteDictionaryData() {
      var self = this
      var data = {
        ids: self.rightClickObj.id
      }
      deleteDictionaryData(data).then(response => {
        var code = '0'
        var content = response.content

        this.getDictionaryList()
        codeValidation(code, content, self)
      })
    },

    // 弹框取消的时候
    hClose() {
      var self = this
      self.$confirm('确认关闭？')
        .then(_ => {
          self.dataDialogVisibleT = false
          self.dialogVisible = false
          self.$refs['from'].resetFields()
          self.$refs['fromT'].resetFields()
          // this.removeMenu()
        })
        .catch(_ => {})
    },

    // 提示是否关闭
    handleClose(done) {
      var self = this
      self.$confirm('确认关闭？')
        .then(_ => {
          done()
          self.$refs['from'].resetFields()
          self.$refs['fromT'].resetFields()
          // this.removeMenu()
        })
        .catch(_ => {})
    }
  }
}
</script>
<style>
  .custom-tree-node {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    padding-right: 8px;
  }

  #menu{
    position: fixed;
    top: 0;
    left: 0;
    z-index: 9999;
    display: none;
  }

  .showMenu{
    background:#e8e8e8;;
    color:#424242;
    text-align: center;
    font-size: 12px;
    border-radius: 5px;
    cursor:pointer
  }

  .showMenu p{
    padding: 10px;
    border-bottom: #d6d1d1 1px solid;
  }
  .showMenu p:last-child{
    border-bottom: 0;
  }
</style>

